#include "httprequestthread.h"
#include "qrcode.h"
#include <QCoreApplication>
#include <QDebug>
#include <QEventLoop>
#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
#include <QSqlRecord>
#include <QXmlStreamReader>


WeFuckCookieJar HttpRequestThread::cookieJar;
QString HttpRequestThread::skey;
QString HttpRequestThread::wxsid;
QString HttpRequestThread::wxuin;
QString HttpRequestThread::pass_ticket;
QString HttpRequestThread::isgrayscale;

HttpRequestThread::HttpRequestThread(QObject *parent) : QObject(parent)
{

}

HttpRequestThread::~HttpRequestThread()
{
    qDebug() << "~HttpRequestThread" << QThread::currentThread();
}

void HttpRequestThread::run()
{
    qDebug() << "run:" << QThread::currentThread();

    // init comp
    QNetworkAccessManager *manager = new QNetworkAccessManager;
    manager->setCookieJar(&cookieJar);

    QEventLoop *loop = new QEventLoop;
    // enter the wechat index website
    connect(manager, SIGNAL(finished(QNetworkReply*)), loop, SLOT(quit()));
    QNetworkRequest request(QUrl("https://wx2.qq.com"));
    QNetworkReply *reply = manager->get(request);
    loop->exec();
//    qDebug() << "aaaa:" <<reply->header(QNetworkRequest::SetCookieHeader).value<QList<QNetworkCookie>>();
    qDebug() << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
    disconnect(manager);

    // get uuid
    QDateTime time = QDateTime::currentDateTime();
    request = QNetworkRequest(QUrl(QString("https://wx2.qq.com/jslogin?redirect_uri=https%3A%2F%2Fwx.qq.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage&appid=wx782c26e4c19acffb&lang=en_US&_=")
                                          + QString::number(time.toTime_t()) + QString("&fun=new")));

    connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(getResponseForUuid(QNetworkReply*)), Qt::DirectConnection);

    manager->get(request);
    qDebug() << "waiting response";

    connect(qrCode, SIGNAL(okChanged()), loop, SLOT(quit()));

//    connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), loop, SLOT(quit()));
    //QThread::wait();
    loop->exec();

    delete manager;
//    delete timer;
    delete loop;
}

void HttpRequestThread::getResponseForUuid(QNetworkReply *reply)
{
    QTimer *timer = new QTimer;
    qDebug() << "getResponseForUuid:" << QThread::currentThread();
    if (reply->error() == QNetworkReply::NoError)
    {
        QByteArray bytes = reply->readAll();
        QString res = bytes;
        QStringList list = res.split("\"");
        qDebug() << list.at(1);
        qrCode->setProperty("uuid", list.at(1));

        QObject::connect(timer, &QTimer::timeout, this, &HttpRequestThread::getQrStatus, Qt::DirectConnection);

        timer->start(1000);

    }
    else
    {
        qDebug() << "finishedSlot errors here";
        qDebug( "found error .... code: %d\n", reply->error());
        qDebug("%s", qPrintable(reply->errorString()));
        this->setProperty("uuid", "fuck");
        this->setProperty("ok", false);
    }
    reply->deleteLater();
}

void HttpRequestThread::getQrStatus()
{
    qDebug() << "getQrStatus:" << QThread::currentThread();

    // get timestamp
    QDateTime time = QDateTime::currentDateTime();

    // output the https router
    QNetworkRequest request(QUrl(QString("https://wx2.qq.com/cgi-bin/mmwebwx-bin/login?")
                                 + QString("loginicon=true&uuid=")
                                 + qrCode->getUuid() + QString("&tip=0&r=-")
                                 + QString::number(time.toTime_t() / 1524)
                                 + QString("&_=") + QString::number(time.toTime_t())));
    QNetworkAccessManager manager;
    manager.setCookieJar(&cookieJar);
    QEventLoop *loop = new QEventLoop();
    connect(&manager, SIGNAL(finished(QNetworkReply*)), loop, SLOT(quit()));
    QNetworkReply *reply = manager.get(request);
    loop->exec();

    QByteArray bytes = reply->readAll();
    QString res = bytes;

    if (res.contains("window.code=408;")) {
        qDebug() << "no message";

    } else if (res.contains("window.code=400;")) {
        qDebug() << "QrCode is outdate";
        qrCode->setStatus(QrCode::LOGIN_STATUS::OUTDATE);
        //timer->stop();
        disconnect(&manager);
        qrCode->setProperty("ok", true);
    } else if (res.contains("window.code=201;")) {
        qDebug() << "QrCode is scanned";
        qrCode->setStatus(QrCode::LOGIN_STATUS::SCAN);
        QString imageUrl = res.split("window.userAvatar = '")[1].split("'")[0];
        qrCode->setImgUrl(imageUrl);
    } else if (res.contains("window.code=200;")) {

        qDebug() << res;
        disconnect(&manager);
        QString indexUri = QString(res).split("window.redirect_uri=\"")[1].split("\"")[0] + "&version=v2" + "&fun=new";
        qDebug() << indexUri;
        QEventLoop loop;
        QNetworkRequest request1(indexUri);

//        request1.setRawHeader("Accept", "text/xml, text/plain, */*");
//        request1.setRawHeader("Accept-Encoding", "gzip, deflate, br");
//        request1.setRawHeader("Accept-Language", "en-US,en;q=0.9");
//        request1.setRawHeader("Connection", "keep-alive");
//        request1.setRawHeader("Host", "wx.qq.com");
//        request1.setRawHeader("Referer", "https://wx.qq.com/?&lang=en_US");
//        request1.setRawHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36");

        reply = manager.get(request1);
        connect(&manager, SIGNAL(finished(QNetworkReply*)), &loop, SLOT(quit()));
        loop.exec();
//        qDebug() << cookieJar.getCookies();
//        qDebug() << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).value<int>();
//        qDebug() << reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
        //cookies->append(QString(reply->rawHeader("Set-Cookie")).split(";")[0]);


//        QByteArray xmlContent = (QString("") + QString(reply->readAll())).toLatin1();
//        QByteArray xmlContent = QString("").toLatin1();
//        qDebug() << xmlContent;
//        QXmlSchema schema;
//        schema.load(xmlContent);
//        qDebug() << schema.isValid();
//        QXmlStreamReader xmlReader(xmlContent);
//        while(!xmlReader.atEnd()) {
//            if(xmlReader.isStartElement()) {

////                QXmlStreamAttributes attributes = xmlReader.attributes();
//                qDebug() << xmlReader.readElementText();
//            }
//            xmlReader.readNext();

//        }
        QString xmlContent = QString(reply->readAll());
        qDebug() << xmlContent;
        skey = xmlContent.split("<skey>")[1].split("</skey>")[0];
        wxuin = xmlContent.split("<wxuin>")[1].split("</wxuin>")[0];
        pass_ticket = xmlContent.split("<pass_ticket>")[1].split("</pass_ticket>")[0];
        isgrayscale = xmlContent.split("<isgrayscale>")[1].split("</isgrayscale>")[0];

        {
            QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "sqlite_for_wefuck");
            db.setDatabaseName("wefuckk.db");
            bool ok = db.open();

            QSqlQuery query(db);
            query.prepare("INSERT INTO user_record (skey, wxuin, pass_ticket, isgrayscale, uuid) values (?, ?, ? ,?, ?)");
            query.bindValue(0, skey);
            query.bindValue(1, wxuin);
            query.bindValue(2, pass_ticket);
            query.bindValue(3, isgrayscale);
            query.bindValue(4, qrCode->getUuid());
            bool success = query.exec();

            if (!success) {
                QSqlError error = query.lastError();
                qDebug() << error.driverText();
            } else {
                qDebug() << "insert 'user_record' successfully";
            }
//            query.exec("SELECT user_id, uuid FROM user_record ORDER BY user_id DESC limit 1");
//            QSqlRecord record = query.record();
//            qDebug()<<"count" << record.count();
//            while(query.next()) {
//                for(int index = 0; index < 10; index++)
//                            qDebug() << query.value(index);
//            }
        }
        QSqlDatabase::removeDatabase("sqlite_for_wefuck");


        qrCode->setStatus(QrCode::LOGIN_STATUS::CONFIRM);

        qrCode->setProperty("ok", true);
    }
    delete loop;

}
